/*
* © 2010 Autodata Solutions Company. All Rights Reserved
* This source code is the confidential and proprietary information of Autodata Solutions Company.
* The user shall not, in whole or in part, copy, publish, disclose or make any use of this source code
* without the prior written consent of Autodata Solutions Company.
*
* File: net/autodata/compare/widgets/AdvantageGrid.js
* Purpose: Provides custom implimintation of the compare advantage grid.
*
* Namespace: net.autodata.compare
* Requires:ExtJS,
*          ASC library - net/autodata/ascjs-ext-debug.js
*/

Ext.ns('net.autodata.compare.AdvantageGrid');
(function() {
    var VFORMAT = net.autodata.compare.data.Format;
    var DATA_DISPLAY_FORMAT = '<span class="dot">&#8226;</span> {0}';
    /**
    * Advantages group column plugin used to render the Advantage Group description once
    * per unique group
    * @class AdvPlugin
    * @private
    */
    var AdvPlugin = Ext.extend(Object, {
        grid: undefined,

        constructor: function(cfg) {
            cfg = cfg || {}
            Ext.apply(cfg, {
                groups: {}
            });

            Ext.apply(this, cfg);

            AdvPlugin.superclass.constructor.call(this, cfg);

            var plugin = this;

            /**
            * Column Renderer
            * @method renderer
            * @param {Object} value The value to be rendered
            * @param {Object} meta columns meta data
            * @param {Ext.data.record} record The Ext.data.Record from which the data was extracted.
            * @return Rendered value
            * @private
            */
            this.renderer = function(value, meta, record) {
                var groupId = record.get('groupId');

                if (plugin.groups[groupId] === true) {
                    return '';
                }

                meta.css = meta.css + ' group-name';

                plugin.groups[groupId] = true;
                return value;
            }
        },

        /**
        * Group column's plugin initilaization function.
        */
        init: function(grid) {
            this.grid = grid;
            this.grid.on('destroy', this.onDestroy, this);
            var view = this.grid.getView();
            view.on('beforerefresh', this.clearGroups, this);

            this.grid.advPlugin = this;
        },

        //Event Handlers

        /**
        * Triggered before the parent grid is rendered, resets the group listing.
        * @method onBeforeRender
        * @private
        */
        clearGroups: function() {
            delete this.groups;
            this.groups = {};
        },

        /**
        * Triggered on the parent grid's destroy, clean up to ensure no function references are left behind to cause a memmory leak
        * @method onDestroy
        * @private
        */
        onDestroy: function() {
            var view = this.grid.getView();
            view.un('beforerefresh', this.clearGroups, this);
            this.grid.un('destroy', this.onDestroy, this);
        }
    });

    /**
    * Advantages Grid grouping view.
    * @class View
    * @private
    */
    var View = Ext.extend(Ext.grid.GroupingView, {
        border: 0,
        startGroup: new Ext.XTemplate(
            '<div id="{groupId}" class="x-grid-group {cls}">',
                '<div id="{groupId}-hd" class="x-grid-group-hd" style="display:none; {style}"></div>',
                '<div id="{groupId}-bd" class="x-grid-group-body">'
        )
    });

    /**
    * ASC compare advtanges grid is an extension of the Ext.grid.GridPanel
    * @class AdvantageGrid
    * @extends Ext.grid.GridPanel
    * @namespace net.autodata.compare.grid
    */
    var AdvantageGrid = Ext.extend(Ext.grid.GridPanel, {
        autoHeight: true,

        width: 778,
        groupWidth: 157,
        advantageWidth: 621,
        autoHeight: true,

        header: true,
        hideHeaders: true,
        disableSelection: true,
        headerAsText: false,
        trackMouseOver: false,

        baseVehicle: undefined,

        competitors: undefined,
        headerFormat: undefined,
        container: undefined,

        constructor: function(cfg) {
            /**
            * @event dataloaded
            * Fires after data has been loaded
            * @param {Ext.grid.GridPanel} this The grid that fired the event
            * @param {Array} records An array of Ext.data.Record objects that the store returned.
            */
            this.addEvents({ 'dataloaded': true });

            cfg = cfg || {};
            var storeCfg = cfg.storeCfg || {};
            delete cfg.storeCfg;

            if (storeCfg.baseParams === undefined) {
                throw 'Advantages grid requires base parameters.';
            }

            var proxy = new net.autodata.data.HttpCacheProxy({
                url: String.format('{0}/Ajax/Grids/Advantages/', ASC.cfg.getLocaleContextPath())
            });

            storeCfg = Ext.apply(storeCfg, {
                reader: new Ext.data.JsonReader({
                    root: '',
                    fields: [{ name: 'groupId', mapping: 'groupName', convert: function(v, record) {
                        return v.replace(/\s/g, "");
                    }
                    },
                    { name: 'groupName' }, { name: 'description'}]
                }),
                proxy: proxy,
                autoLoad: false,
                groupField: 'groupName',
                listeners: {
                    'loadexception': this.onLoadException,
                    'load': this.onLoad,
                    scope: this
                }
            });

            cfg.store = new Ext.data.GroupingStore(storeCfg);

            var scrollOffset = cfg.scrollOffset;
            delete cfg.scrollOffset;
            
            var view = new View({
                forceFit: true,
                enableNoGroups: false,
                enableGroupingMenu: false,
                showGroupName: false,
                scrollOffset: scrollOffset
            });

            var col = new AdvPlugin({ id: 'group', header: 'group', width: this.groupWidth, sortable: false, dataIndex: 'groupName' });

            var plugins = [].concat(cfg.plugins);
            delete cfg.plugins;
            plugins.push(col);

            var headerCfg = cfg.headerCfg || {};
            delete cfg.headerCfg;

            Ext.apply(headerCfg, {
                cls: 'compare-header-advantages'
            });

            Ext.apply(cfg, {
                enableDragDrop: false,
                enableColumnResize: false,
                enableColumnMove: false,
                enableColumnHide: false,
                enableHdMenu: false,
                trackMouseOver: false,
                border: true,
                headerCfg: headerCfg,
                cls: 'compare-advantages-grid',
                view: view,
                columns: [
                    { id: 'groupName', header: 'groupName', width: 0, sortable: false, dataIndex: 'groupName', hidden: true },
                    col,
                    { id: 'desc', header: 'description', width: this.advantageWidth, sortable: false, dataIndex: 'description', renderer: this.dataRenderer }
                ],
                plugins: plugins
            });


            AdvantageGrid.superclass.constructor.call(this, cfg);
        },

        init: function(panel) {
            if (panel) {
                panel.on('destroy', this.destroy);
                this.container = panel;
            }
        },

        initComponent: function() {
            AdvantageGrid.superclass.initComponent.apply(this, arguments);

            var panel = this.getContainer();

            if (panel) {
                var tb = panel.getToolbar();
                tb.init(this);
            }

            var view = this.getView();
            view.init(this);
            this.relayEvents(view, ['change', 'remove']);

            if (!this.headerFormat) {
                this.headerFormat = ASC.message('net.autodata.compare.grid.advantages.title.vehicle-display');
            }

            if (this.baseVehicle && typeof this.baseVehicle !== '') {
                var bv = this.baseVehicle;
                if (bv) {
                    bv = VFORMAT.ymmt(bv);
                }

                this.baseVehicle = bv;
            }

            this.initTemplates();
        },

        initTemplates: function() {
            var ts = this.templates || {};
            if (!ts.headerTpl) {

                ts.headerTpl = new Ext.XTemplate(
					'<h5></h5>',
					'{text}',
					{
					    compile: true,
					    disableFormats: true
					}
				);
            }

            this.templates = ts;
        },

        dataRenderer: function(value, meta, record) {
            return String.format(DATA_DISPLAY_FORMAT, value);
        },

        /**
        * Retrieve the containing element
        * @method getContainer
        * @param {Object}
        */
        getContainer: function() {
            return this.container;
        },

        /**
        * Supply the vehicles this panel is supposed to display and trigger the load
        * @method setVehicles
        * @param {Vehicle[]} vehicles Array of Vehicle objects (Base/Competitor)
        */
        setVehicles: function(baseVehicle, competitors) {
            if (baseVehicle == null) {
                throw 'The baseVehicle parameter cannot be null';
            }

            this.baseVehicle = baseVehicle;
            this.competitors = competitors;
        },

        /**
        * Finding the matching vehicle information for the given acode
        * @param {String} acode
        * @return {String} vehicle information string or undefined
        */
        getVehicle: function(acode) {
            for (var i = 0; i < this.competitors.length; i++) {
                var competitor = this.competitors[i];
                if (competitor && competitor.acode === acode) {
                    return VFORMAT.ymmt(competitor);
                }
            }

            return undefined;
        },

        // Event Handlers

        /**
        * Advantages grid on render event handler
        * @method onDestroy
        * @private
        */
        onRender: function() {
            AdvantageGrid.superclass.onRender.apply(this, arguments);
            if (this.header && this.templates.headerTpl) {
                this.header.clean();
                this.templates.headerTpl.append(this.header, { text: ASC.message('net.autodata.compare.grid.advantages.title.text') });
            }
        },

        /**
        * Advantages grid on destroy event handler
        * @method onDestroy
        * @private
        */
        onDestroy: function() {
            if (this.container) {
                this.container.un('destroy', this.destroy);
                delete this.container;
            }

            AdvantageGrid.superclass.onDestroy.apply(this, arguments);
        },

        /**
        * Stores on load exeption event handler.
        * @method onLoadException
        * @private
        */
        onLoadException: function() {
            var store = this.getStore();
            var records = [];
            if (store) {
                store.removeAll();
            }

            this.fireEvent('dataloaded', this, records);
        },

        /**
        * Stores on load exeption event handler.
        * @method onLoadException
        * @private
        */
        onLoad: function() {
            var store = this.getStore();
            var records = [];
            if (store) {
                records = store.getRange()
            }

            this.fireEvent('dataloaded', this, records);
        },

        /**
        * Custom override for grid's set title to allow for the search of the h5 tag.
        * Sets the title text for the panel and optionally the {@link #iconCls icon class}.
        * @method setTitle
        */
        setTitle: function(title, iconCls) {
            this.title = title;
            if (this.header) {
                if (this.headerAsText) {
                    this.header.child('span').update(title);
                }
                else if (this.templates.headerTpl) {
                    this.header.child('h5').update(title);
                }
            }

            if (iconCls) {
                this.setIconClass(iconCls);
            }
            this.fireEvent('titlechange', this, title);

            return this;
        },

        /**
        * Grids on vehicle selected event handler.
        * @method onVehicleSelected
        * @param {String} acode The selected competitors acode.
        * @private
        */
        onVehicleSelected: function(acode) {
            var store = this.getStore();
            store.removeAll();

            if (acode) {
                var competitor = this.getVehicle(acode);
                var title = '';

                if (this.headerFormat) {
                    title = String.format(this.headerFormat, VFORMAT.ymmt(this.baseVehicle), competitor);
                }

                this.setTitle(title);

                Ext.apply(store.baseParams, {
                    competitorAcode: acode
                });

                store.load();
            }
        }
    });

    net.autodata.compare.AdvantageGrid = AdvantageGrid;
})();
